/*
 * Copyright (c) 2018-2999 湖南洛云网络科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 */

package com.yami.shop.api.controller;


import cn.hutool.core.util.StrUtil;
import com.yami.shop.bean.dto.FlowLogDto;
import com.yami.shop.bean.model.FlowLog;
import com.yami.shop.common.config.Constant;
import com.yami.shop.service.FlowLogService;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Objects;


/**
 * 用户流量记录
 *
 * @author YXF
 * @date 2020-07-13 13:18:33
 */
@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("/flowAnalysisLog" )
@Api(tags="用户记录接口")
public class FlowLogController {

    private final FlowLogService flowLogService;
    private final RedisTemplate redisTemplate;
    private final MapperFacade mapperFacade;

    public static final String UNKNOWN = "unknown";

    public static final String LOCALHOST = "127.0.0.1";


    /**
     * 新增用户流量记录
     * @param flowLogDto 用户流量记录
     * @return 是否新增成功
     */
    @PostMapping
    public ResponseEntity<Boolean> save(@RequestBody @Valid FlowLogDto flowLogDto, HttpServletRequest request) {
        FlowLog flowLog = mapperFacade.map(flowLogDto, FlowLog.class);
        flowLog.setCreateTime(new Date());
        flowLog.setIp(getIp(request));
        // 数据为空，打印日志
        if(Objects.isNull(flowLog.getPageId()) || Objects.isNull(flowLog.getUuid()) || Objects.isNull(flowLog.getUuidSession()) ||
                Objects.isNull(flowLog.getVisitType()) || Objects.isNull(flowLog.getStep()) ||Objects.isNull(flowLog.getSystemType())){
            log.info("用户流量记录数据为空：" + flowLog.toString());
            return ResponseEntity.ok(false);
        }
        // 记录存入缓存中
        redisTemplate.opsForSet().add(Constant.FLOW_ANALYSIS_LOG,flowLog);
        int flowMaxSize = 5000;
        // 没有开启定时任务，或者缓存数据量过大时，提交一次数据
        if (redisTemplate.opsForSet().size(Constant.FLOW_ANALYSIS_LOG) > flowMaxSize){
            flowLogService.insertBatch();
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 获取用户ip
     * @param request
     * @return
     */
    private String getIp(HttpServletRequest request){
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || UNKNOWN.equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (LOCALHOST.equals(ipAddress)) {
                    // 根据网卡取本机配置的IP
                    try {
                        ipAddress = InetAddress.getLocalHost().getHostAddress();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                }
            }
            // 通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null) {
                if (ipAddress.contains(StrUtil.COMMA)) {
                    return ipAddress.split(StrUtil.COMMA)[0];
                } else {
                    return ipAddress;
                }
            } else {
                return "";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return  "";
        }
    }
}
